home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Camelot / Camelot 043 (1989-06)(Swedish User Group of Amiga)(SE)(PD)[WB].zip / Camelot 043 (1989-06)(Swedish User Group of Amiga)(SE)(PD)[WB].adf / printfx / printfx.c < prev    next >
C/C++ Source or Header  |  1989-06-08  |  10KB  |  373 lines

  1. char *Cr="PrintFx 2.7  09-MAY-89 by D.W.Reisig, NL 1151AV10\n";
  2. char *WTTl=" PrintFx 2.7 ";
  3.  
  4. /*
  5.  
  6. This code is a good example how NOT to write a program. Then why
  7. did I include the source?
  8. This is a utility that I made when I had the Amiga one month or so.
  9. And I could not get my files to my printer without printing over
  10. the perforation, or it stopped halfway the sheet when the printing
  11. was done. Annyway I got irritated.
  12. I have an Epson FX80+. I thought that made this program useless
  13. for other printers. Suddenly the hole world can use it on their
  14. printers as well. This is why I included the source. Perhaps it
  15. does not work on your printer. Now you can change it (if you can
  16. decipher the code).
  17. I used Lattice 5.02 and Asm 5.02 as compilers but 4.00 does it also
  18. fine.
  19.  
  20. */
  21.  
  22.  
  23. #include <libraries/dos.h>
  24. #include <setjmp.h>>
  25. #include <exec/types.h>
  26. #include <intuition/intuition.h>
  27.  
  28. #define CMDNAMES 1    /* one inputfile                 */
  29. #define ISM 64        /* init string max                */
  30. #define IOBUFFER 512    /* twice allocated from the stack        */
  31. #define RMARGINIT 255    /* means: not used                */
  32. #define UNIT_INCH 216    /* there are 216 1/3 units in a inch        */
  33. #define EOF -1        /*                        */
  34. #define ESC 0x1b    /*                        */
  35. #define SKIPOVERA 198    /* skip-over space in 1/3 dots if back shift    */
  36. #define SKIPOVERB 264   /* skip-over space if not shifted back        */
  37. #define PERFSHIFT 54    /* paper shift back at start in 1/3 dots    */
  38. #define ERROR -1    /* Used with longjump in an error situation    */
  39. #define    STOP 1        /* Used with longjump in a non error situation    */
  40.  
  41. jmp_buf Mains;        /* easy does it                    */
  42. char DeinitPaper[]={ ESC,'J',PERFSHIFT,ESC,'C',0,0 } ;
  43. #define DEINITLEN 7    /* size of DeinitPaper[]            */
  44. char *Path[CMDNAMES+1];
  45. char *Title=NULL;    /* title available                */
  46. int  Infile;        /* DOS file handler                */
  47. int  Prt;        /* DOS file handler                */
  48. int  Page=0;        /* printer determines pagelength        */
  49. int  Lmarg=5;        /* left margin                    */
  50. int  Rmarg=RMARGINIT;    /* right margin not given            */
  51. int  Cpline;        /* will contain number of possible chars/line    */
  52. int  Mode=64;        /* 64=unused                    */
  53. int  Lsp=29;        /* Linespace .13456" 3.41mm 82 l/p        */
  54. int  Type=1;        /* type is elite                */
  55. int  Plen=11;        /* paper length    in inches            */
  56. int  SpPTab=8;        /* Spaces per Tab (make an option of it iyl    */
  57. char *Pr;        /* Name of this utility from cmdline        */
  58. char Cond=0;        /* not condensed                */
  59. char Empha=0;        /* not emphasized                */
  60. char Double=0;        /* not double strike                */
  61. char Prop=0;        /* not proportional                */
  62. char Super=0;        /* super script is off                */
  63. char Trunc=1;        /* truncation line overflow            */
  64. char PlBack=1;        /* paper is pulled back at start        */
  65. char EndDet=1;        /* paper end detection on            */
  66. char OutStd=0;        /* Output not standard; PAR:            */
  67. char Let='\f';        /* last character send to printer, if it is FF,    */
  68.             /* no extra FF must be sent, and no FF if    */
  69.             /* nothing has been printed            */
  70. char Er=1;        /* stderr may be used                */
  71.  
  72. void ps(),ErrMsg(),Explain();
  73. char gc();
  74. extern int ConOut;
  75.  
  76.  
  77. main(argc,argv)
  78. register int argc;
  79. register char *argv[];
  80. {
  81.   register int argcnt, namecnt, ret, err=0;
  82.  
  83.   Pr=argv[0];  /* adapt name the user uses */
  84.   if (argc>1){
  85.     if (*argv[1]=='?'){
  86.       Explain();
  87.       return(0);
  88.     }
  89.   }
  90.   for (argcnt=1,namecnt=0;argcnt<argc;++argcnt) if (*(argv[argcnt])!='-'){
  91.     Path[namecnt++]=argv[argcnt];
  92.     if (namecnt>CMDNAMES) break;
  93.   }
  94.   procopts(argc,argv);
  95.   if (namecnt>CMDNAMES){
  96.     ErrMsg("Donot know what to do with: ",Path[CMDNAMES]);
  97.     return(0);
  98.   }
  99.   if (calc()) return(0); /* some things must be calculated */
  100.  
  101.   if (Path[0]){
  102.     if ((Infile=Open(Path[0],MODE_OLDFILE))==0){
  103.       ErrMsg("Cannot open: ",Path[0]);
  104.       return(0);
  105.     }
  106.   } else Infile=Input();
  107.   if (!OutStd){
  108.     if ((Prt=Open("PAR:",MODE_OLDFILE))==0){
  109.       ErrMsg("No printer (PAR:)","");
  110.       goto CleanUp;
  111.     }
  112.   } else Prt=Output();
  113.   ret=setjmp(Mains);    /* return point from deep level errors */
  114.   if (ret) goto CleanUp;
  115.   MakeOffSwitch(WTTl);  /* nice to stop when you did RUN pr.. */
  116.  
  117.   initprinter();
  118.   filetoprinter();
  119.   deinitprinter();
  120.   goto CleanUp1;
  121.  
  122. CleanUp:
  123.   if (ret==ERROR)  err=IoErr();
  124.  
  125. CleanUp1:
  126.   RemOffSwitch();
  127.   if (!OutStd)  Close(Prt);
  128.   if (Path[0])  Close(Infile);
  129.   return(err);
  130. }   /* main */
  131.  
  132.  
  133. procopts(argc,argv)
  134. register int argc;
  135. register char *argv[];
  136. {
  137.   register int argcnt;
  138.   register char *option, *error, avail;
  139.   int temp;
  140.   for (argcnt=1;argcnt<argc;++argcnt){
  141.     if (*(option=argv[argcnt])=='-'){
  142.       avail=1;
  143.       while (avail) switch(*(error=option++)){
  144.  
  145. case '-'  : break;
  146. case '\0' : avail=0; break;
  147. case '?'  : if (*option=='?') ConMsg(Cr); else Explain();  XCEXIT(0);
  148. case 't'  : Title  =(*option=='=')?option+1:option; avail=0; break;
  149. case 'i'  : option+=stoi(option,&Plen);   break;
  150. case 'l'  : option+=stoi(option,&Lmarg);  break;
  151. case 'r'  : option+=stoi(option,&Rmarg);  break;
  152. case 'p'  : option+=stoi(option,&temp);
  153.             if (temp==0) Type&=0xfe;
  154.             else Page=temp;
  155.             break;
  156. case 'm'  : option+=stoi(option,&Mode);   break;
  157. case 'n'  : option+=stoi(option,&Lsp);    break;
  158. case 'c'  : Type|=0x04;  break;
  159. case 'e'  : switch(*(option++)){
  160.               case 'd' : EndDet=0;    break;
  161.               case 'l' : Type|=0x01;  break;
  162.               case 'm' : Type|=0x08;  break;
  163.               case 'n' : Type|=0x20;  break;
  164.               default  : goto opterr;
  165.             }
  166. case 'd'  : Type|=0x10;  break;
  167. case 'v'  : Prop=1;      break;
  168. case 'x'  : Trunc=0;     break;
  169. case 'y'  : PlBack=0;     break;
  170. case 'o'  : OutStd=1;    break;
  171. case 's'  : Er=0;     break;
  172. case 'q'  : Super=1;     break;
  173. default   : goto opterr;
  174.  
  175.   } } } return(0);
  176. opterr:
  177.   Explain();
  178.   ErrMsg("Unknown option: -",error);
  179.   XCEXIT(0);
  180. }   /* procopts */
  181.  
  182.  
  183. calc()
  184. {
  185.   register int choose, avail;
  186.   register unsigned char *data;
  187.   if (Mode==64)   Mode=Type;
  188.   data="\x50\x60\x28\x30\x89\xA0\x44\x50";
  189.   choose=(int)Mode&0x05;    /* b0 on is elite, b2 on is condensed */
  190.   if (Mode&0x20) choose+=0x02;    /* b1 on is enlarged */ 
  191.   Cpline=(int)*(data+choose);
  192.   if (Rmarg!=RMARGINIT){
  193.     if (Rmarg>Cpline){
  194.       ErrMsg("Right margin too large","");
  195.       return(-1);
  196.     }
  197.   } else Rmarg=Cpline;
  198.   Cpline=Rmarg-Lmarg;
  199.   avail=((Plen*UNIT_INCH)-((PlBack)?SKIPOVERA:SKIPOVERB))/Lsp;
  200.   if (Page){
  201.     if (Page>avail){
  202.       ErrMsg("You ask too much lines per page","");
  203.       return(-1);
  204.     }
  205.   } else Page=avail;
  206.   return(0);
  207. }
  208.  
  209.  
  210. initprinter()
  211. {
  212.   char initstring[ISM];
  213.   register char *is=initstring;
  214.   register int len;
  215.  
  216.   if (PlBack){
  217.     *(is++)=ESC;   *(is++)='j';   *(is++)=PERFSHIFT;
  218.   }
  219.   *(is++)=ESC;   *(is++)='@';
  220.   *(is++)=ESC;   *(is++)='C';   *(is++)=0;     *(is++)=Plen;
  221.   *(is++)=ESC;   *(is++)='!';   *(is++)=Mode;
  222.   if (Prop)    { *(is++)=ESC;   *(is++)='p';   *(is++)='1';    }
  223.   *(is++)=ESC;   *(is++)=EndDet?'9':'8';  
  224.   *(is++)=ESC;   *(is++)='3';   *(is++)=Lsp;
  225.   if (Lmarg)   { *(is++)=ESC;   *(is++)='l';   *(is++)=Lmarg;  }
  226.   *(is++)=ESC;   *(is++)='Q';   *(is++)=Rmarg;
  227.   if (Super)   { *(is++)=ESC;   *(is++)='S';   *(is++)='0';    }
  228.   
  229.   len=is-initstring;
  230.   if (Write(Prt,initstring,len)!=len) longjmp(Mains,ERROR);
  231.   return(0);
  232. }
  233.  
  234.  
  235. deinitprinter()
  236. {
  237.   if (Let!='\f') if (Write(Prt,"\f",1)!=1) longjmp(Mains,ERROR);
  238.   if (PlBack){
  239.     DeinitPaper[DEINITLEN-1]=Plen;  /* FF button works ok now */
  240.     if (Write(Prt,DeinitPaper,DEINITLEN)!=DEINITLEN) longjmp(Mains,ERROR);
  241.   }
  242.   return(0);
  243. }
  244.  
  245.  
  246.  
  247. char *Inb, *Outb;  /* two buffer pointer global from here on */
  248.  
  249.  
  250. filetoprinter()
  251. {
  252.   char inbuffer[IOBUFFER], outbuffer[IOBUFFER];  /* from the stack */
  253.   register int line, i;
  254.   register char c;
  255.   
  256.   Inb=inbuffer; Outb=outbuffer;
  257.  
  258.   i=Lmarg;  
  259.   line=newpage();
  260.   while (1){
  261.     c=gc();
  262. check:
  263.     if (c=='\t') i+=(SpPTab-((i-Lmarg)%SpPTab));  /* expand tabs */
  264.     else ++i;
  265.     if (c=='\n'){                   /* newline */
  266.       i=Lmarg;
  267.       line=newline(line);
  268.     } else if (c=='\f'){            /* formfeed, newline inherent */
  269.       i=Lmarg;
  270.       line=newpage(line);
  271.     } else if (i>Rmarg){            /* R-marge reached: newline */
  272.       i=Lmarg;
  273.       line=newline(line);
  274.       if (Trunc) trunc();           /* skip rest of line  */
  275.       else goto check;              /* no, print rest on next line */
  276.     } else pc(c);
  277.     if (c==EOF) break;
  278.   }
  279.   return(0);  
  280. }
  281.  
  282.  
  283. newline(line)
  284. register int line;
  285. {
  286.   ++line;
  287.   if (line>=Page)  line=newpage();
  288.   else  pc('\n');
  289.   return(line);
  290. }
  291.  
  292.  
  293. trunc()
  294. {
  295.   char t;
  296.   while ((t=gc())>=0) if (t=='\n') break;
  297.   return(0);
  298. }
  299.  
  300.  
  301. newpage()
  302. {
  303.   static pagenr=0;
  304.   register out, factor, tpagenr, nr;
  305.   char ptd;
  306.   if ((pagenr)&&(Let!='\f')) ps("\r\f");
  307.   ++pagenr;
  308.   if (Title){
  309.     out=0;
  310.     ps("page "); out+=5;
  311.     for (tpagenr=pagenr,factor=1000,ptd=0;factor;factor/=10){
  312.       if (nr=(tpagenr/factor)) ptd=1;
  313.       if (ptd){
  314.         pc(nr+0x30);
  315.         ++out;
  316.     tpagenr-=(nr*factor);
  317.       }
  318.     }
  319.     for (;out<10;++out) pc(' ');
  320.     ps(Title); out+=strlen(Title);
  321.     factor=Cpline-strlen(Path[0])-Lmarg;
  322.     while (out++<factor) pc(' ');
  323.     ps(Path[0]);
  324.     ps("\n\n");
  325.     return(2); /* now two lines used */
  326.   }
  327.   return(0); /* no title; no lines used */
  328. }
  329.     
  330.   
  331.  
  332. char gc()  /* return a char, if buffer empty ask dos for more */
  333. {
  334.   static avail=0, pos=0;
  335.   
  336.   if (avail==0){
  337.     if ((avail=Read(Infile,Inb,IOBUFFER))<1){
  338.       if (avail<0) longjmp(Mains,ERROR);
  339.       return(EOF);
  340.     }
  341.     pos=0;
  342.   }
  343.   --avail;
  344.   return(*(Inb+pos++));
  345. } /* gc */
  346.  
  347.  
  348. void ps(string)
  349. register char *string;
  350. {
  351.   while (*string) pc(*(string++));
  352. }
  353.  
  354.  
  355. pc(c)  /* store a char, if buffer full, flush it */
  356. char c;
  357. {
  358.   static pos=0;
  359.  
  360.   if (c!=EOF){
  361.     Let=*(Outb+pos++)=c;
  362.     if (pos<IOBUFFER) return(0);
  363.   }
  364.   if ((TestOffSwitch())||(SetSignal(0,0x3000)&0x3000)){
  365.     deinitprinter();
  366.     longjmp(Mains,STOP);
  367.   }
  368.   if (Write(Prt,Outb,pos)!=pos) longjmp(Mains,ERROR);
  369.   pos=0;
  370.   return(0);
  371. } /* pc */
  372.  
  373.